/**
 *	@file	np_sub.c
 *	@brief	アンノーンノートアプリ サブ
 *	@author	Miyuki Iwasawa
 *	@date	08.08.04
 *
 */

#include "common.h"
#include "system/procsys.h"
#include "system/bmp_list.h"
#include "system/bmp_menu.h"
#include "system/arc_util.h"
#include "system/arc_tool.h"
#include "system/snd_tool.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "system/msgdata.h"
#include "system/buflen.h"
#include "system/window.h"
#include "system/brightness.h"
#include "system/clact_util.h"
#include "system/clact_tool.h"
#include "system/render_oam.h"
#include "system/palanm.h"
#include "system/wipe.h"
#include "system/window.h"
#include "system/font_arc.h"
#include "system/winframe.naix"
#include "gflib/touchpanel.h"
#include "poketool/pokeicon.h"
#include "poketool/monsno.h"
#include "msgdata/msg.naix"
#include "msgdata/msg_an_note.h"

#include "savedata/config.h"
#include "application/an_note.h"
#include "an_note_sys.h"
#include "an_note_sub.h"
#include "an_note_snd_def.h"

#include "an_note_gra.naix"
#include "data/clact_util/clact_header.naix"
#include "poketool/icongra/poke_icon.naix"

enum{
 EXE_CODE_CANCEL,
 EXE_CODE_UP,
 EXE_CODE_DOWN,
 EXE_CODE_MAX,
};

static const TCATS_OAM_INIT an_note_coi = {
	0,128,		///< メイン	OAM管理領域・開始/終了
	0,32,		///< メイン	アフィン管理領域・開始/終了
	0,128,		///< サブ	OAM管理領域・開始/終了
	0,32,		///< サブ	アフィン管理領域・開始/終了
};
static const TCATS_CHAR_MANAGER_MAKE an_note_ccmm = {
	AN_NOTE_ACTRES_MAX,	//ID制御数
	64*1024,	//メイン画面管理サイズ(byte単位) 0/64kbyte
	16*1024,	//サブ画面管理サイズ(byte単位) 0/16kbyte
	GX_OBJVRAMMODE_CHAR_1D_32K,	//メインOBJモード指定
	GX_OBJVRAMMODE_CHAR_1D_32K,	//サブOBJモード指定
};

///TCATS_RES_ARC
static const TCATS_RESOURCE_FILE_LIST an_note_actres_list = {
	NARC_clact_header_an_note_chr_resdat,	// キャラクタ
	NARC_clact_header_an_note_pal_resdat,		// パレット
	NARC_clact_header_an_note_cell_resdat,	// セル
	NARC_clact_header_an_note_canm_resdat,	// セルアニメ
	TCATS_RESID_NULL,							// マルチセル
	TCATS_RESID_NULL,							// マルチセルアニメ
	NARC_clact_header_an_note_celact_cldat		// ヘッダー
};


typedef struct _AN_MEMO{
	u16	msg_idx:6;
	u16	msg_ct:2;
	u16	open_lv:8;
}AN_MEMO;

typedef struct _AN_NOTE_PAGE{
	AN_MEMO	up;
	AN_MEMO	down;
}AN_NOTE_PAGE;


static const AN_NOTE_PAGE DATA_AnNotePage[MEMO_PAGE_MAX] = {
 {{msg_memo01,1,AN_MEMO_PUZZLE2},	{msg_memo02,1,AN_MEMO_PUZZLE2}},
 {{msg_memo03,1,AN_MEMO_PUZZLE3},	{msg_memo04,1,AN_MEMO_PUZZLE4}},
 {{msg_memo05,1,AN_MEMO_GET_ATOZ},	{msg_memo06,1,AN_MEMO_GET_ATOZ}},
 {{msg_memo07,1,AN_MEMO_MOJINOMA1},	{msg_memo08,1,AN_MEMO_MOJINOMA4}},
 {{msg_memo09,3,AN_MEMO_MAP_OPEN},	{msg_memo10,1,AN_MEMO_MAP_OPEN}},
 {{msg_memo11,1,AN_MEMO_ALL_GET},	{msg_memo12,1,AN_MEMO_ALL_GET}},
};

////////////////////////////////////////////////////////////////
///プロトタイプ
////////////////////////////////////////////////////////////////
static int sub_InputExe(AN_NOTE_WORK* wk,int code);
static int sub_KeyInput(AN_NOTE_WORK* wk);
static int sub_TouchInput(AN_NOTE_WORK* wk,BOOL* touch_f);

static void sub_DrawTopPage(AN_NOTE_WORK* wk);
static void sub_DrawListPage(AN_NOTE_WORK* wk,u8 page_idx);
static void sub_DrawMemoPage(AN_NOTE_WORK* wk,u8 page_idx);

static void sub_ScrnChange(AN_NOTE_WORK* wk,NOTE_SCR* scr,int frame);
static void sub_MsgPrintEx(GF_BGL_BMPWIN* win,STRBUF* str,int font,u16 x,u16 y);
static void sub_MsgPrint(GF_BGL_BMPWIN* win,STRBUF* str,u16 x,u16 y);




static void AnNoteVBlank(void * work);

static void sub_VBankSet(void);
static void sub_BGLInit(AN_NOTE_WORK* wk);
static void sub_BGLRelease(AN_NOTE_WORK* wk);
static void sub_ScrnDataGet(NOTE_SCR* sp,ARCHANDLE* handle,int id,int heapID);
static void sub_2DResInit(AN_NOTE_WORK* wk);
static void sub_2DResRelease(AN_NOTE_WORK* wk);
static void sub_MsgDataInit(AN_NOTE_WORK* wk);
static void sub_MsgDataRelease(AN_NOTE_WORK* wk);
static void sub_BmpWinAdd(AN_NOTE_WORK* wk);
static void sub_BmpWinDel(AN_NOTE_WORK* wk);

static void sub_ActorSysInit(AN_NOTE_WORK* wk);
static void sub_ActorSysRelease(AN_NOTE_WORK* wk);
static void sub_ActorInit(AN_NOTE_WORK* wk);
static void sub_ActorRelease(AN_NOTE_WORK* wk);
static void sub_ActorObjMake(AN_NOTE_WORK* wk);
static void sub_ActorObjDelete(AN_NOTE_WORK* wk);
static void sub_IconActorResChange(AN_NOTE_WORK* wk, int idx,int form);
static void sub_PageButtonSet(AN_NOTE_WORK* wk);

////////////////////////////////////////////////////////////////
///グローバル関数
////////////////////////////////////////////////////////////////
/**
 *	@brief	リソース初期化
 */
void AnNoteResInit(AN_NOTE_WORK* wk)
{
	sub_BGLInit( wk );
	sub_2DResInit( wk );
	sub_MsgDataInit( wk );
	sub_BmpWinAdd( wk );
	sub_ActorInit( wk );

	sys_VBlankFuncChange(AnNoteVBlank, wk);
}

/**
 *	@brief	リソース解放
 */
void AnNoteResRelease(AN_NOTE_WORK* wk)
{
	sub_ActorRelease( wk );
	sub_BmpWinDel( wk );
	sub_MsgDataRelease( wk );
	sub_2DResRelease( wk );
	sub_BGLRelease( wk );
}

/**
 *	@brief	初期画面描画
 */
void AnNoteInitialDraw(AN_NOTE_WORK* wk)
{
	int i;

	AnNoteSub_BackButtonWrite(wk,BACK_BTN_ACTIVE);
	AnNoteSub_DrawPage(wk,wk->page);
}

/**
 *	@brief	入力取得
 */
int AnNoteSub_GetInput(AN_NOTE_WORK* wk)
{
	int ret;
	BOOL touch_f = FALSE;

	ret = sub_TouchInput(wk,&touch_f);
	if(touch_f){
		return ret;
	}
	return sub_KeyInput(wk);
}

/**
 *	@brief	メモページMAX数を取得
 */
u8 AnNoteSub_GetMemoPageMax(AN_NOTE_WORK* wk)
{
	int i;
	const AN_NOTE_PAGE* page;
	for(i = 0;i < MEMO_PAGE_MAX;i++){
		page = &DATA_AnNotePage[i];

		if( page->up.open_lv > wk->an_memo_open ){
			break;
		}
	}
	return i;
}

void AnNoteSub_DrawPage(AN_NOTE_WORK* wk,u8 page)
{
	GF_BGL_BmpWinDataFill(&wk->win[WIN_MSGU],0);
	GF_BGL_BmpWinDataFill(&wk->win[WIN_MSGD],0);
	GF_BGL_BmpWinDataFill(&wk->win[WIN_PAGE],0);

	if(wk->page == 0){
		sub_DrawTopPage(wk);
	}else if((wk->page-1) < wk->an_page_max){
		sub_DrawListPage(wk,wk->page-1);
	}else{
		sub_DrawMemoPage(wk,wk->page-(wk->an_page_max+1));
	}

	//ページ番号表示
	WORDSET_RegisterNumber( wk->msg.wset, 0,
		wk->page+1 , 1, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_RegisterNumber( wk->msg.wset, 1,
		wk->page_max , 1, NUMBER_DISPTYPE_LEFT, NUMBER_CODETYPE_HANKAKU );
	WORDSET_ExpandStr( wk->msg.wset, wk->msg.str ,wk->msg.page);
	GF_STR_PrintColor( &wk->win[WIN_PAGE], FONT_SYSTEM, wk->msg.str,
		0,0, MSG_NO_PUT, FCOL_N_WHITE, NULL );

	GF_BGL_BmpWinOnVReq(&wk->win[WIN_MSGU]);
	GF_BGL_BmpWinOnVReq(&wk->win[WIN_MSGD]);
	GF_BGL_BmpWinOnVReq(&wk->win[WIN_PAGE]);

	sub_PageButtonSet(wk);
}

/**
 *	@brief	戻るボタン描画
 */
void AnNoteSub_BackButtonWrite(AN_NOTE_WORK* wk,BACK_BTN_STATE state)
{
	u32 siz;
	static const GF_PRINTCOLOR col[] = {
	 GF_PRINTCOLOR_MAKE(FBMP_COL_BLUE,FBMP_COL_WHITE,0),
	 GF_PRINTCOLOR_MAKE(FBMP_COL_BLACK,FBMP_COL_WHITE,0),
	};

	CLACT_AnmChg(wk->pAct[ACT_BACK], ANM_BACK+state);
	CLACT_AnmReStart( wk->pAct[ACT_BACK]);

	GF_BGL_BmpWinDataFill( &wk->win[WIN_BACK], 0);

	siz = FontProc_GetPrintStrWidth( FONT_TOUCH, wk->msg.back, 0 );
	GF_STR_PrintColor( &wk->win[WIN_BACK], FONT_TOUCH, wk->msg.back,
		((BMP_BACK_SX*8)-siz)/2,0, MSG_NO_PUT, col[0], NULL );

	GF_BGL_BmpWinOnVReq(&wk->win[WIN_BACK]);
}

/**
 *	@brief	戻るボタン　アニメ状態チェック
 */
BOOL AnNoteSub_BackButtonIsAnime(AN_NOTE_WORK* wk)
{
	return CLACT_AnmActiveCheck( wk->pAct[ACT_BACK] );
}

////////////////////////////////////////////////////////////////
///ローカル関数
////////////////////////////////////////////////////////////////
static int sub_InputExe(AN_NOTE_WORK* wk,int code)
{
	switch(code){
	case EXE_CODE_CANCEL:
		Snd_SePlay(SND_NOTE_BACK);
		AnNoteSub_BackButtonWrite(wk,BACK_BTN_ANM);
		return SEQ_FADE_OUT;
	case EXE_CODE_UP:
		if(wk->page == 0){
			return SEQ_MAIN;
		}
		wk->page--;
		CLACT_AnmChg( wk->pAct[ACT_UP], ANM_UP_A );
		Snd_SePlay(SND_NOTE_PAGE);
		return SEQ_PAGE_CHG;
	case EXE_CODE_DOWN:
		if(wk->page >= (wk->page_max-1)){
			return SEQ_MAIN;
		}
		wk->page++;
		CLACT_AnmChg( wk->pAct[ACT_DOWN], ANM_DOWN_A );
		Snd_SePlay(SND_NOTE_PAGE);
		return SEQ_PAGE_CHG;
	}
	return SEQ_MAIN;
}

/**
 *	@brief	キー入力取得
 */
static int sub_KeyInput(AN_NOTE_WORK* wk)
{
	if(sys.trg & PAD_BUTTON_KTST_CHG){
		wk->key_mode = APP_KTST_KEY;
	}

	if(sys.trg & PAD_BUTTON_CANCEL){
		return sub_InputExe(wk,EXE_CODE_CANCEL);
	}
	if(sys.trg & PAD_KEY_UP){
		return sub_InputExe(wk,EXE_CODE_UP);
	}
	if(sys.trg & PAD_KEY_DOWN){
		return sub_InputExe(wk,EXE_CODE_DOWN);
	}
	return SEQ_MAIN;
}

/**
 *	@brief	タッチ入力取得
 */
static int sub_TouchInput(AN_NOTE_WORK* wk,BOOL* touch_f)
{
	int ret;

	static const RECT_HIT_TBL TpRect[] = {
	//	{0,191,0,255}, ty,by,lx,rx
		{TP_BACK_Y,TP_BACK_Y+TP_BACK_H,TP_BACK_X,TP_BACK_X+TP_BACK_W},
		{TP_UP_Y,TP_UP_Y+TP_UP_H,TP_UP_X,TP_UP_X+TP_UP_W},
		{TP_DOWN_Y,TP_DOWN_Y+TP_DOWN_H,TP_DOWN_X,TP_DOWN_X+TP_DOWN_W},
		{RECT_HIT_END,0,0,0},
	};
	ret = GF_TP_HitTrg(TpRect);

	if(ret == RECT_HIT_NONE){
		return SEQ_MAIN;
	}
	*touch_f = TRUE;
	wk->key_mode = APP_KTST_TOUCH;

	return sub_InputExe(wk,ret);
}


/**
 *	@brief	タイトルページ描画
 */
static void sub_DrawTopPage(AN_NOTE_WORK* wk)
{
	int i;

	sub_ScrnChange(wk,&wk->su_top,UFRM_NOTE);
	sub_ScrnChange(wk,&wk->sd_top,DFRM_NOTE);
	for(i = 0;i < ICON_ACTMAX;i++){
		CATS_ObjectEnableCap(wk->pAIcon[i], CATS_ENABLE_FALSE);
	}

	//タイトル描画
	MSGMAN_GetString(wk->msg.man,msg_title_u,wk->msg.str);
	sub_MsgPrint(&wk->win[WIN_MSGU],wk->msg.str,MU_TITLE_X,MU_TITLE_Y);

	sub_MsgPrint(&wk->win[WIN_MSGU],wk->msg.name,
		MU_NAME_X-FontProc_GetPrintStrWidth( FONT_SYSTEM, wk->msg.name, 0), MU_NAME_Y );

	MSGMAN_GetString(wk->msg.man,msg_title_d,wk->msg.str);
	sub_MsgPrint(&wk->win[WIN_MSGD],wk->msg.str,MD_TITLE_X,MD_TITLE_Y);

	MSGMAN_GetString(wk->msg.man,msg_an_num,wk->msg.tmp);
	WORDSET_RegisterNumber( wk->msg.wset, 0,
		wk->an_get_num , 2, NUMBER_DISPTYPE_SPACE, NUMBER_CODETYPE_DEFAULT );
	WORDSET_ExpandStr( wk->msg.wset, wk->msg.str ,wk->msg.tmp);
	sub_MsgPrint(&wk->win[WIN_MSGD],wk->msg.str,MD_NUM_X,MD_NUM_Y);
}

/**
 *	@brief	アンノーンリストページ描画
 *
 *	@param	idx	リストページインデックス
 */
static void sub_DrawListPage(AN_NOTE_WORK* wk,u8 page_idx)
{
	int i,num,idx;

	sub_ScrnChange(wk,&wk->su_list,UFRM_NOTE);
	sub_ScrnChange(wk,&wk->sd_list,DFRM_NOTE);

	num = page_idx*ICON_ACTMAX;
	for(i = 0;i < ICON_ACTMAX;i++){
		idx = num+i;
		if(idx >= wk->an_get_num){
			CATS_ObjectEnableCap(wk->pAIcon[i], CATS_ENABLE_FALSE);
			continue;
		}
		CATS_ObjectEnableCap(wk->pAIcon[i], CATS_ENABLE_TRUE);

		sub_IconActorResChange(wk,i,wk->an_get_form[idx]);
		MSGMAN_GetString(wk->msg.man,msg_an01+wk->an_get_form[idx],wk->msg.str);

		if(i < ICON_LINEMAX){
			sub_MsgPrint(&wk->win[WIN_MSGU],wk->msg.str,MU_ANNOON_X,MU_ANNOON_Y+i*MU_ANNOON_OY);
		}else{
			sub_MsgPrint(&wk->win[WIN_MSGD],wk->msg.str,MD_ANNOON_X,MD_ANNOON_Y+(i-ICON_LINEMAX)*MD_ANNOON_OY);
		}
	}
}

/**
 *	@brief	アンノーンメモページ描画
 */
static void sub_DrawMemoPage(AN_NOTE_WORK* wk,u8 page_idx)
{
	int i;
	const AN_NOTE_PAGE* pd;

	if(page_idx == 0){
		sub_ScrnChange(wk,&wk->su_memo,UFRM_NOTE);
		sub_ScrnChange(wk,&wk->sd_memo,DFRM_NOTE);
		for(i = 0;i < ICON_ACTMAX;i++){
			CATS_ObjectEnableCap(wk->pAIcon[i], CATS_ENABLE_FALSE);
		}
	}


	//上画面メモ
	pd = &DATA_AnNotePage[page_idx];
	if(pd->up.open_lv <= wk->an_memo_open){
		for(i = 0;i < pd->up.msg_ct;i++){
			MSGMAN_GetString(wk->msg.man,pd->up.msg_idx+i,wk->msg.str);

			if(pd->up.msg_idx+i == msg_memo09_01){
				sub_MsgPrintEx(&wk->win[WIN_MSGU],wk->msg.str,FONT_UNKNOWN,MU_MEMO_X,0);
			}else{
				sub_MsgPrint(&wk->win[WIN_MSGU],wk->msg.str,MU_MEMO_X,MU_MEMO_Y);
			}
		}
	}
	//下画面メモ
	if(pd->down.open_lv <= wk->an_memo_open){
		for(i = 0;i < pd->down.msg_ct;i++){
			MSGMAN_GetString(wk->msg.man,pd->down.msg_idx+i,wk->msg.str);
			sub_MsgPrint(&wk->win[WIN_MSGD],wk->msg.str,MD_MEMO_X,MD_MEMO_Y);
		}
	}
}

/**
 *	@brief	BGスクリーン書換え
 */
static void sub_ScrnChange(AN_NOTE_WORK* wk,NOTE_SCR* scr,int frame)
{
	GF_BGL_ScrWriteExpand(wk->bgl,frame,
		0,0,32,24,scr->dat,0,0,scr->siz_x,scr->siz_y);
	GF_BGL_LoadScreenV_Req(wk->bgl,frame);
}

/**
 *
 */
static void sub_MsgPrintEx(GF_BGL_BMPWIN* win,STRBUF* str,int font,u16 x,u16 y)
{
	GF_STR_PrintColor( win, font, str,
		x,y, MSG_NO_PUT, FCOL_N_BLACK, NULL );
}

/**
 *	@brief	メッセージ描画
 */
static void sub_MsgPrint(GF_BGL_BMPWIN* win,STRBUF* str,u16 x,u16 y)
{
	sub_MsgPrintEx(win,str,FONT_SYSTEM,x,y);
}

////////////////////////////////////////////////////////////////
//リソース初期化
////////////////////////////////////////////////////////////////
/**
 *	@brief	VBlank関数
 */
static void AnNoteVBlank(void * work)
{
	AN_NOTE_WORK* wk = (AN_NOTE_WORK*)work;

	//アクター転送
	if(wk->pActSys != NULL){
		CATS_RenderOamTrans();
	}
	DoVramTransferManager();	//Vram転送マネージャ実行
	GF_BGL_VBlankFunc( wk->bgl );
	OS_SetIrqCheckFlag( OS_IE_V_BLANK);
}

/**
 *	@brief	vramバンク設定
 */
static void sub_VBankSet(void)
{
	GF_BGL_DISPVRAM vramSetTable = {
		GX_VRAM_BG_128_A,				// メイン2DエンジンのBG
		GX_VRAM_BGEXTPLTT_NONE,			// メイン2DエンジンのBG拡張パレット
		GX_VRAM_SUB_BG_128_C,			// サブ2DエンジンのBG
		GX_VRAM_SUB_BGEXTPLTT_NONE,		// サブ2DエンジンのBG拡張パレット
		GX_VRAM_OBJ_64_E,				// メイン2DエンジンのOBJ
		GX_VRAM_OBJEXTPLTT_NONE,		// メイン2DエンジンのOBJ拡張パレット
		GX_VRAM_SUB_OBJ_16_I,			// サブ2DエンジンのOBJ
		GX_VRAM_SUB_OBJEXTPLTT_NONE,	// サブ2DエンジンのOBJ拡張パレット
		GX_VRAM_TEX_NONE,				// テクスチャイメージスロット
		GX_VRAM_TEXPLTT_NONE			// テクスチャパレットスロット
	};
	GF_Disp_SetBank( &vramSetTable );
}
/*
 *	@brief	BGL初期化
 */
static void sub_BGLInit(AN_NOTE_WORK* wk)
{
	sub_VBankSet();

	wk->bgl = GF_BGL_BglIniAlloc(wk->heapID);
	{	//BG SYSTEM
		GF_BGL_SYS_HEADER BGsys_data = {
			GX_DISPMODE_GRAPHICS,GX_BGMODE_0,GX_BGMODE_0,GX_BG0_AS_2D
		};
		GF_BGL_InitBG(&BGsys_data);
	}
	//上画面をサブ,下画面をメインに切り替え
	GX_SetDispSelect(GX_DISP_SELECT_SUB_MAIN);

	{	// 上画面　テキスト面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			UFRM_MSG_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, UFRM_MSG, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, UFRM_MSG );
	}

	{	// 上画面　ノート面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			UFRM_NOTE_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, UFRM_NOTE, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, UFRM_NOTE );
	}

	{	// 上画面　背景
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			UFRM_BACK_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, UFRM_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, UFRM_BACK );
	}

	{	// 下画面　テキスト面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf800, GX_BG_CHARBASE_0x10000, GX_BG_EXTPLTT_01,
			DFRM_MSG_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_MSG, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_MSG );
	}
	{	// 下画面　ノート面
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xf000, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			DFRM_NOTE_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_NOTE, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_NOTE );
	}

	{	// 下画面　背景
		GF_BGL_BGCNT_HEADER TextBgCntDat = {
			0, 0, 0x800, 0, GF_BGL_SCRSIZ_256x256, GX_BG_COLORMODE_16,
			GX_BG_SCRBASE_0xe800, GX_BG_CHARBASE_0x00000, GX_BG_EXTPLTT_01,
			DFRM_BACK_PRI, 0, 0, FALSE
		};
		GF_BGL_BGControlSet( wk->bgl, DFRM_BACK, &TextBgCntDat, GF_BGL_MODE_TEXT );
		GF_BGL_ScrClear( wk->bgl, DFRM_BACK );
	}

	GF_BGL_ClearCharSet( UFRM_MSG, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( UFRM_NOTE, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( UFRM_BACK, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_MSG, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_NOTE, 32, 0, wk->heapID );
	GF_BGL_ClearCharSet( DFRM_BACK, 32, 0, wk->heapID );
}

/**
 * @brief	BGL解放
 */
static void sub_BGLRelease(AN_NOTE_WORK* wk)
{

	GF_BGL_BGControlExit(wk->bgl, DFRM_BACK );
	GF_BGL_BGControlExit(wk->bgl, DFRM_NOTE );
	GF_BGL_BGControlExit(wk->bgl, DFRM_MSG );
	GF_BGL_BGControlExit(wk->bgl, UFRM_BACK );
	GF_BGL_BGControlExit(wk->bgl, UFRM_NOTE );
	GF_BGL_BGControlExit(wk->bgl, UFRM_MSG );

	sys_FreeMemoryEz(wk->bgl);

	//上画面をメイン,下画面をサブに戻す
	GX_SetDispSelect(GX_DISP_SELECT_MAIN_SUB);
}

/**
 *	@brief	スクリーンデータ取得
 */
static void sub_ScrnDataGet(NOTE_SCR* sp,ARCHANDLE* handle,int id,int heapID)
{
	sp->buf = ArcUtil_HDL_ScrnDataGet(handle,id,TRUE,&sp->scr,heapID);
	sp->siz_x = sp->scr->screenWidth/8;
	sp->siz_y = sp->scr->screenHeight/8;
	sp->dat = (u8*)sp->scr->rawData;
}

/**
 * @brief	2Dリソース初期化
 */
static void sub_2DResInit(AN_NOTE_WORK* wk)
{
	ARCHANDLE* handle;

	//アーカイブのハンドルを取得
	handle = ArchiveDataHandleOpen(ARC_AN_NOTE_GRA,wk->heapID);

	//メイン下画面背景転送
	ArcUtil_HDL_PalSet( handle,
			NARC_an_note_gra_bgd_nclr,PALTYPE_MAIN_BG, 0, 0, wk->heapID);
	ArcUtil_HDL_BgCharSet( handle,
			NARC_an_note_gra_bgd_lz_ncgr, wk->bgl, DFRM_BACK, 0, 0, TRUE, wk->heapID);
	ArcUtil_HDL_ScrnSet( handle,
			NARC_an_note_gra_bgd_base_lz_nscr, wk->bgl, DFRM_BACK, 0, 0, TRUE, wk->heapID);

	//サブ上画面背景転送
	ArcUtil_HDL_PalSet( handle,
			NARC_an_note_gra_bgu_nclr,PALTYPE_SUB_BG, 0, 0, wk->heapID);
	ArcUtil_HDL_BgCharSet( handle,
			NARC_an_note_gra_bgu_lz_ncgr, wk->bgl, UFRM_BACK, 0, 0, TRUE, wk->heapID);
	ArcUtil_HDL_ScrnSet( handle,
			NARC_an_note_gra_bgu_base_lz_nscr, wk->bgl, UFRM_BACK, 0, 0, TRUE, wk->heapID);

	sub_ScrnDataGet(&wk->su_top,handle,NARC_an_note_gra_bgu_top_lz_nscr,wk->heapID);
	sub_ScrnDataGet(&wk->su_list,handle,NARC_an_note_gra_bgu_list_lz_nscr,wk->heapID);
	sub_ScrnDataGet(&wk->su_memo,handle,NARC_an_note_gra_bgu_memo_lz_nscr,wk->heapID);
	sub_ScrnDataGet(&wk->sd_top,handle,NARC_an_note_gra_bgd_top_lz_nscr,wk->heapID);
	sub_ScrnDataGet(&wk->sd_list,handle,NARC_an_note_gra_bgd_list_lz_nscr,wk->heapID);
	sub_ScrnDataGet(&wk->sd_memo,handle,NARC_an_note_gra_bgd_memo_lz_nscr,wk->heapID);

	ArchiveDataHandleClose( handle );

	//会話ウインドウグラフィック転送
	TalkWinGraphicSet(wk->bgl,DFRM_MSG,
		BMP_TALK_WIN_CGX, BMP_TALK_WIN_PAL,wk->win_type, wk->heapID);
	TalkFontPaletteLoad( PALTYPE_MAIN_BG, TALK_FONT_PAL*0x20, wk->heapID );
	TalkFontPaletteLoad( PALTYPE_SUB_BG, TALK_FONT_PAL*0x20, wk->heapID );

}

/**
 * @brief	2Dリソース解放
 */
static void sub_2DResRelease(AN_NOTE_WORK* wk)
{
	sys_FreeMemoryEz(wk->sd_memo.buf);
	sys_FreeMemoryEz(wk->sd_list.buf);
	sys_FreeMemoryEz(wk->sd_top.buf);
	sys_FreeMemoryEz(wk->su_memo.buf);
	sys_FreeMemoryEz(wk->su_list.buf);
	sys_FreeMemoryEz(wk->su_top.buf);
}

/**
 *	@brief	メッセージデータ初期化
 */
static void sub_MsgDataInit(AN_NOTE_WORK* wk)
{
	int i;

	//タッチフォントロード
	FontProc_LoadFont(FONT_TOUCH,wk->heapID);

	wk->msg.man = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,
			NARC_msg_an_note_dat,wk->heapID);

	wk->msg.wset = WORDSET_CreateEx(WORDSET_AN_NOTE_BUFNUM,WORDSET_AN_NOTE_BUFLEN,wk->heapID);
	wk->msg.tmp = STRBUF_Create(AN_NOTE_MSG_BUFLEN,wk->heapID);
	wk->msg.str = STRBUF_Create(AN_NOTE_MSG_BUFLEN,wk->heapID);

	wk->msg.back = MSGMAN_AllocString(wk->msg.man,msg_back);
	wk->msg.page = MSGMAN_AllocString(wk->msg.man,msg_page);
	wk->msg.name = MyStatus_CreateNameString(SaveData_GetMyStatus(wk->param->save), wk->heapID);
}

/**
 *	@brief	メッセージデータ解放
 */
static void sub_MsgDataRelease(AN_NOTE_WORK* wk)
{
	int i;

	//文字列バッファ削除
	STRBUF_Delete(wk->msg.name);
	STRBUF_Delete(wk->msg.page);
	STRBUF_Delete(wk->msg.back);
	STRBUF_Delete(wk->msg.str);
	STRBUF_Delete(wk->msg.tmp);
	WORDSET_Delete(wk->msg.wset);

	MSGMAN_Delete(wk->msg.man);

	//タッチフォントアンロード
	FontProc_UnloadFont(FONT_TOUCH);
}

/**
 *	@brief	BMPウィンドウ初期化
 */
static void sub_BmpWinAdd(AN_NOTE_WORK* wk)
{
	int i;
	static const BMPWIN_DAT BmpWinData[] = {
	 {	// 「もどるボタン」
		BMP_BACK_FRM, BMP_BACK_PX, BMP_BACK_PY,
		BMP_BACK_SX, BMP_BACK_SY, BMP_BACK_PAL, BMP_BACK_CGX
	 },
	 {	// 「本文メッセージウィンドウ」
		BMP_MSGU_FRM, BMP_MSGU_PX, BMP_MSGU_PY,
		BMP_MSGU_SX, BMP_MSGU_SY, BMP_MSGU_PAL, BMP_MSGU_CGX
	 },
	 {	// 「本文メッセージウィンドウ」
		BMP_MSGD_FRM, BMP_MSGD_PX, BMP_MSGD_PY,
		BMP_MSGD_SX, BMP_MSGD_SY, BMP_MSGD_PAL, BMP_MSGD_CGX
	 },
	 {	// 「ページ番号ウィンドウ」
		BMP_PAGE_FRM, BMP_PAGE_PX, BMP_PAGE_PY,
		BMP_PAGE_SX, BMP_PAGE_SY, BMP_PAGE_PAL, BMP_PAGE_CGX
	 },
	};

	for( i=0; i<WIN_MAX; i++ ){
		GF_BGL_BmpWinAddEx( wk->bgl, &wk->win[i], &BmpWinData[i] );
		GF_BGL_BmpWinDataFill( &wk->win[i], 0 );
	}

	//YesNoボタンシステムワーク確保
	wk->ynbtn_wk = TOUCH_SW_AllocWork(wk->heapID);
}

/**
 *	@brief	BMPウィンドウ解放
 */
static void sub_BmpWinDel(AN_NOTE_WORK* wk)
{
	int i;
	for( i=0; i<WIN_MAX; i++ ){
		GF_BGL_BmpWinOff( &wk->win[i] );
		GF_BGL_BmpWinDel( &wk->win[i] );
	}
	//YesNoボタンシステムワーク解放
	TOUCH_SW_FreeWork( wk->ynbtn_wk );
}

/**
 *	@brief	セルアクターシステム初期化
 */
static void sub_ActorSysInit(AN_NOTE_WORK* wk)
{
	int i;

	initVramTransferManagerHeap(32,wk->heapID);

	//セルアクターシステム初期化
	wk->pActSys = CATS_AllocMemory(wk->heapID);

	CATS_SystemInit( wk->pActSys,
		&an_note_coi,&an_note_ccmm,AN_NOTE_ACTPAL_NUM );

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
	REND_OAM_UtilOamRamClear_Sub(wk->heapID);

	//セルアクターリソース初期化
	wk->pActRes = CATS_ResourceCreate(wk->pActSys);
	CATS_ClactSetInit( wk->pActSys, wk->pActRes,AN_NOTE_ACTMAX);

	CATS_ResourceLoadBinaryEx( wk->pActSys, wk->pActRes,
		&an_note_actres_list,CATS_CGXOFS_AREA,CATS_PLTTOFS_AREA);

	// アイテムアイコンリソース初期化
	{
		const TCATS_RESOURCE_NUM_LIST resNum = {
			ICON_ACTMAX,	///< キャラの数
			1,	///< パレットの数
			1,	///< セルの数
			1,	///< セルアニメの数
			0,	///< マルチセルの数
			0,	///< マルチセルアニメの数
		};

		wk->pActIconRes = CATS_ResourceCreate(wk->pActSys);
		CATS_ResourceManagerInit(wk->pActSys,wk->pActIconRes,&resNum);
		//セルアクターセットは流用
		CATS_SetClactSetPtr(wk->pActIconRes,CATS_GetClactSetPtr(wk->pActRes));

		//アイコンアクターハンドル取得
		wk->icon_h = ArchiveDataHandleOpen(ARC_POKEICON,wk->heapID);

		//リソース追加
		CATS_LoadResourcePlttArcH(
			wk->pActSys,wk->pActIconRes,wk->icon_h,
			PokeIconPalArcIndexGet(),0,1,NNS_G2D_VRAM_TYPE_MAX,ACTRES_ICON);

		CATS_LoadResourceCellArcH(
			wk->pActSys,wk->pActIconRes,wk->icon_h,
				PokeIconCellArcIndexGet(),0,ACTRES_ICON);

		CATS_LoadResourceCellAnmArc(
			wk->pActSys,wk->pActIconRes,ARC_POKEICON,
			PokeIconCellAnmArcIndexGet(),0,ACTRES_ICON);

		for(i = 0;i < ICON_LINEMAX; i++){
			CATS_LoadResourceCharArcH(
				wk->pActSys, wk->pActIconRes,wk->icon_h,
				PokeIconCgxArcIndexGetByMonsNumber( MONSNO_ANNOON, FALSE, i),
				0,NNS_G2D_VRAM_TYPE_2DSUB,ACTRES_ICON+i);
		}
		for(i = ICON_LINEMAX;i < ICON_ACTMAX; i++){
			CATS_LoadResourceCharArcH(
				wk->pActSys, wk->pActIconRes,wk->icon_h,
				PokeIconCgxArcIndexGetByMonsNumber( MONSNO_ANNOON, FALSE, i),
				0,NNS_G2D_VRAM_TYPE_2DMAIN,ACTRES_ICON+i);
		}
	}
}

/**
 *	@brief	セルアクターシステム解放
 */
static void sub_ActorSysRelease(AN_NOTE_WORK* wk)
{
	//リソース解放
	CATS_ResourceDestructor_S(wk->pActSys,wk->pActIconRes);
	CATS_ResourceDestructor(wk->pActSys,wk->pActRes);
	wk->pActIconRes = NULL;
	wk->pActRes = NULL;

	ArchiveDataHandleClose( wk->icon_h );

	//システムワーク解放
	CATS_FreeMemory(wk->pActSys);
	wk->pActSys = NULL;
	DellVramTransferManager();

	//OAM初期化
	REND_OAM_UtilOamRamClear_Main(wk->heapID);
}

/*
 *	@brief	セルアクター初期化
 */
static void sub_ActorInit(AN_NOTE_WORK* wk)
{
	sub_ActorSysInit(wk);
	sub_ActorObjMake(wk);

	GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_ON );
}

/**
 *	@brief	セルアクター解放
 */
static void sub_ActorRelease(AN_NOTE_WORK* wk)
{
	GF_Disp_GXS_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_OFF );
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_OBJ, VISIBLE_OFF );

	sub_ActorObjDelete(wk);
	sub_ActorSysRelease(wk);
}

/**
 *	@brief	セルアクターオブジェクト作成
 */
static void sub_ActorObjMake(AN_NOTE_WORK* wk)
{
	int i;
	u8	idx;

	static const TCATS_OBJECT_ADD_PARAM	ActAddParam[] =
	{
		{	// 戻るボタン
			ACTRES_NORMAL,	//ID
			ACT_BACK_PX, ACT_BACK_PY, 0,	//x,y,z
			ANM_BACK, ACT_SPRI_BACK, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// UPカーソル
			ACTRES_NORMAL,	//ID
			ACT_UP_PX, ACT_UP_PY, 0,	//x,y,z
			ANM_UP, ACT_SPRI_UP, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
		{	// DOWNカーソル
			ACTRES_NORMAL,	//ID
			ACT_DOWN_PX, ACT_DOWN_PY, 0,	//x,y,z
			ANM_DOWN, ACT_SPRI_DOWN, 0, NNS_G2D_VRAM_TYPE_2DMAIN,	//anmNO,pri,pal,d_area
			TCATS_PALMODE_AUTO, 0, 0, 0	//prm1,prm2,prm3,prm4
		},
	};

	for(i = 0;i < NORMAL_ACTMAX;i++){
		wk->pAct[i] = CATS_ObjectAdd( wk->pActSys, wk->pActRes, &ActAddParam[i] );
//		CLACT_SetAnmFrame(wk->pAct[i], FX32_ONE);
		CLACT_SetDrawFlag(wk->pAct[i], TRUE );
		CLACT_SetAnmFlag(wk->pAct[i], TRUE);
		CLACT_BGPriorityChg( wk->pAct[i], DFRM_NOTE_PRI );
	}

	//アイコンアクター追加
	{
		TCATS_OBJECT_ADD_PARAM_S	prm;

		MI_CpuClear8(&prm,sizeof(TCATS_OBJECT_ADD_PARAM_S));

		prm.bg_pri = ACT_ICON_BGPRI;		///< 優先順位
		prm.pal = PokeIconPalNumGet(MONSNO_ANNOON,0,FALSE);	///< パレット番号
		prm.vram_trans = 0;	///< 描画エリア

		prm.x = ACT_ICON_PX;	///< X座標
		prm.id[1] = ACTRES_ICON;	//Pal
		prm.id[2] = ACTRES_ICON;	//Cell
		prm.id[3] = ACTRES_ICON;	//Cell Anime
		prm.id[4] = CLACT_U_HEADER_DATA_NONE;	//Multi Cell
		prm.id[5] = CLACT_U_HEADER_DATA_NONE;	//Muiti Cell Anime

		for(i = 0;i < ICON_ACTMAX;i++){
			if(i < ICON_LINEMAX){
				prm.y = ACT_ICON_PYU+(i*ACT_ICON_OY);	//y
				prm.d_area = NNS_G2D_VRAM_TYPE_2DSUB;	///< 描画エリア
			}else{
				prm.y = ACT_ICON_PYD+((i-ICON_LINEMAX)*ACT_ICON_OY);	//y
				prm.d_area = NNS_G2D_VRAM_TYPE_2DMAIN;	///< 描画エリア
			}
			prm.id[0] = ACTRES_ICON+i;	//char

			wk->pAIcon[i] = CATS_ObjectAdd_S(wk->pActSys,wk->pActIconRes,&prm);
			CATS_ObjectEnableCap(wk->pAIcon[i], CATS_ENABLE_FALSE);
		}
	}
}

/**
 *	@brief	セルアクターオブジェクト削除
 */
static void sub_ActorObjDelete(AN_NOTE_WORK* wk)
{
	int i;

	for(i = 0;i < ICON_ACTMAX;i++){
		if(wk->pAIcon[i] != NULL){
			CATS_ActorPointerDelete_S(wk->pAIcon[i]);
		}
	}
	for(i = 0;i < NORMAL_ACTMAX;i++){
		if(wk->pAct[i] != NULL){
			CLACT_Delete(wk->pAct[i]);
		}
	}
}

/**
 *	@brief	アイコンアクターリソース読み替え
 */
static void sub_IconActorResChange(AN_NOTE_WORK* wk, int idx,int form)
{
	CATS_ChangeResourceCharArcH( wk->pActSys, wk->pActIconRes, wk->icon_h,
		PokeIconCgxArcIndexGetByMonsNumber( MONSNO_ANNOON, FALSE, form), 0, ACTRES_ICON+idx);
}

/**
 *	@brief	ページボタン状態セット
 */
static void sub_PageButtonSet(AN_NOTE_WORK* wk)
{
	if((wk->page_max == 1) || (wk->page == 0)){
		CLACT_AnmChg( wk->pAct[ACT_UP], ANM_UP_N );
	}else{
		CLACT_AnmChg( wk->pAct[ACT_UP], ANM_UP );
	}
	if((wk->page_max == 1) || (wk->page == (wk->page_max-1))){
		CLACT_AnmChg( wk->pAct[ACT_DOWN], ANM_DOWN_N );
	}else{
		CLACT_AnmChg( wk->pAct[ACT_DOWN], ANM_DOWN );
	}
}
